GdiPlus Objects

In Microsoft documentation, GDI+ objects—such as GpGraphics, GpBitmap, GpBrush, GpPen, etc.—are described as abstract “objects” manipulated via Flat API functions. However, these are not true objects in the object-oriented sense. They are actually opaque pointers to undocumented C-style structures.

Each GDI+ object is a pointer to a structure with a well-defined memory layout. These structures contain fields for internal state, handles, flags, and configuration data. The Flat API functions (e.g. GdipSetPenWidth, GdipGetImageBounds) are essentially accessors and mutators—they read or write values to these internal fields.

For example, the GpCustomLineCap “object”, is a pointer to the following structure:

typedef struct {
    CustomLineCapType type;
    GpPathData pathdata;
    BOOL fill;
    GpLineCap cap;
    REAL inset;
    GpLineJoin join;
    REAL scale;
} GpCustomLineCap;

So when you call:

GdipSetCustomLineCapWidthScale(cap, 1.5)

…it’s just setting cap->scale = 1.5.

Big APIs like the Windows GDI+ flat API—tend to expose enormous functionality through low‑level procedural calls. They are powerful, but also verbose, error‑prone, and difficult to use safely. Every object must be created manually, destroyed manually, passed as a pointer, and handled with strict lifetime discipline. A single missing cleanup call or an incorrect pointer cast can destabilize an entire application.

AfxNova takes a different approach. Instead of building a heavy framework with deep inheritance trees, virtual methods, and opaque abstractions, AfxNova wraps these large APIs using tiny, lightweight classes—each one focused on a single GDI+ object.

The philosophy is simple:

  1. Wrap the object, not the API

Each GDI+ object—GpGraphics, GpBitmap, GpPen, GpBrush, etc.—is represented by a small class whose only job is to manage: * creation * destruction * ownership * pointer access

The class does not attempt to replace the API. It simply makes the API safe and pleasant to use.

  1. Automatic lifetime management

Every class uses RAII semantics: * the constructor creates the underlying GDI+ object * the destructor frees it automatically * This eliminates leaks, double frees, and forgotten cleanup calls—problems that plague raw GDI+ code.

  1. Full transparency and zero lock‑in

AfxNova never hides the underlying pointer. Every class exposes: * object → the raw GDI+ pointer @object → the address of the pointer (for functions that require GpObject**)

This means the developer can always call the flat API directly whenever needed. Nothing is trapped behind an abstraction.

  1. No inheritance, no frameworks, no ceremony

Each class is self‑contained. There is no base class, no virtual destructor, no hierarchy, no “framework rules” to follow.

This keeps the system: * predictable * easy to read * easy to maintain * easy to extend

And it avoids the complexity that often appears in Microsoft’s own wrappers.

  1. A consistent, minimal interface

All classes follow the same pattern: * a constructor that initializes the object * a destructor that frees it * an operator to expose the pointer * optional helper methods for convenience

This uniformity makes the entire API intuitive. Once you learn one class, you understand them all.

  1. 100% compatibility with the flat API

Because the classes are thin wrappers, they remain fully compatible with: * all GDI+ functions * all Win32 functions * mixed GDI/GDI+ rendering + custom drawing pipelines + user‑defined message loops + any external library that expects raw pointers

This is not a framework—it is a safety layer.

The result is a system that preserves the full power of the underlying API while eliminating its friction. Developers get: * the safety of RAII * the clarity of object‑oriented syntax * the transparency of raw pointers * the flexibility of procedural APIs * the simplicity of tiny, focused classes

AfxNova does not try to redesign GDI+. It simply makes GDI+ usable.

The file AfxGdipObjects.inc, contains the complete set of these tiny classes for all major GDI+ objects. Each class is small, predictable, and easy to understand—yet together they form a robust, safe, and modern interface to a large and complex graphics subsystem.


The following table lists all lightweight RAII wrappers provided by AfxNova for opaque GDI+ objects (raw pointers to hidden internal structures).

AfxNova Class GDI+ Object Purpose/Description
GdiPlusAdjustableArrowCap GpAdjustableArrowCap Builds a line cap that looks like an arrow.
GdiPlusBitmap GpBitmap Expands on the capabilities of the Image functions by providing additional methods for creating and manipulating raster images.
GdiPlusBrush GpBrush Base wrapper for all brush types.
GdiPlusCustomLineCap GpCustomLineCap Wraps custom line caps defined by paths.
GdiPlusEffect GpEffect Wraps GDI+ effects.
GdiPlusFont GpFont Font wrapper for text rendering.
GdiPlusGraphics GpGraphics Wraps a GDI+ graphics context.
GdiPlusGraphicsPath GpPath Wraps a graphics path; building, modifying, and disposing paths.
GdiPlusHatchBrush GpHatchBrush Hatch-style brush.
GdiPlusImage GpImage Loads, clones, and manages images from files, streams, and resources.
GdiPlusImageAttributes GpImageAttributes Image attributes (color adjustments, gamma, color matrices).
GdiPlusLinearGradientBrush GpLinearGradientBrush Linear gradient brush.
GdiPlusMatrix GpMatrix Transformation matrix; translation, rotation, scaling, etc.
GdiPlusObjects GDI+ Startup/Shutdown RAII wrapper for GDI+ initialization and shutdown.
GdiPlusPathGradientBrush GpPathGradientBrush Gradient brush that interpolates from boundary path to center color.
GdiPlusPathIterator GpPathIterator Iterates over path subpaths, types, and markers.
GdiPlusPen GpPen Wraps a pen for drawing lines and outlines.
GdiPlusRegion GpRegion Region wrapper for clipping and hit-testing.
GdiPlusSolidBrush GpSolidBrush Solid color brush.
GdiPlusStringFormat GpStringFormat Text layout and formatting options
GdiPlusTextureBrush GpTextureBrush Brush that fills using an image.

GdiPlusObjects

Initializes and shutdowns GDI+.

' ========================================================================================
' Constructor - Initializes GDI+
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusObjects
   DIM StartupInput AS GdiplusStartupInput
   StartupInput.GdiplusVersion = 1   ' Version must be 1
   GdiplusStartup(@m_token, @StartupInput, NULL)
END CONSTRUCTOR
' ========================================================================================

' ========================================================================================
' Dstructor - Shutdowns GDI+
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusObjects
   IF m_token THEN GdiplusShutdown(m_token)
END DESTRUCTOR
' ========================================================================================

Example

' ########################################################################################
' Microsoft Windows
' File: Gdip_CreateAdjustableArrowCap.bas
' Contents: GDI+ Flat API - Gdip_CreateAdjustableArrowCap example
' Compiler: FreeBasic 32 & 64 bit
' Copyright (c) 2025 José Roca. Freeware. Use at your own risk.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################

#define _WIN32_WINNT &h0602
'#define _GDIP_DEBUG_ 1
#INCLUDE ONCE "AfxNova/AfxGdipObjects.inc"
#INCLUDE ONCE "AfxNova/CGraphCtx.inc"
USING AfxNova

CONST IDC_GRCTX = 1001

DECLARE FUNCTION wWinMain (BYVAL hInstance AS HINSTANCE, _
                           BYVAL hPrevInstance AS HINSTANCE, _
                           BYVAL pwszCmdLine AS WSTRING PTR, _
                           BYVAL nCmdShow AS LONG) AS LONG

   END wWinMain(GetModuleHandleW(NULL), NULL, wCOMMAND(), SW_NORMAL)

' // Forward declaration
DECLARE FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

' ========================================================================================
' The following example creates two AdjustableArrowCap objects, arrowCapStart and
' arrowCapEnd, and sets the fill mode to TRUE. The code then creates a Pen object and
' assigns arrowCapStart as the starting line cap for this Pen object and arrowCapEnd as
' the ending line cap. Next, draws a line.
' ========================================================================================
SUB Example_CreateAdjustableArrowCap (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   DIM dpiRatio AS SINGLE = graphics.DpiRatio
   graphics.ScaleTransform(dpiRatio)

   ' // Create an AdjustableArrowCap that is filled.
   DIM arrowCapStart AS GdiPlusAdjustableArrowCap = GdiPlusAdjustableArrowCap(10, 10, TRUE)
   ' // Adjust to DPI by setting the scale width
   GdipSetCustomLineCapWidthScale(arrowCapStart, dpiRatio)

   ' // Create an AdjustableArrowCap that is not filled.
   DIM arrowCapEnd AS GdiPlusAdjustableArrowCap = GdiPlusAdjustableArrowCap(15, 15, FALSE)
   ' // Adjust to DPI by setting the scale width
   GdipSetCustomLineCapWidthScale(arrowCapEnd, dpiRatio)

   ' // Get the type of CustomLineCap
   ' // It will return 1 (CustomLineCapTypeAdjustableArrow)
   DIM nType AS CustomLineCapType
   GdipGetCustomLineCapType(arrowCapEnd, @nType)

   ' // Create a Pen
   DIM arrowPen AS GdiPlusPen = GdiPlusPen(ARGB_Violet, 1)

   ' // Assign arrowCapStart as the start cap.
   GdipSetPenCustomStartCap(arrowPen, arrowCapStart)
   ' // Assign arrowCapEnd as the end cap.
   GdipSetPenCustomEndCap(arrowPen, arrowCapEnd)

   ' // Draw a line using arrowPen.
   GdipDrawLine(graphics, arrowPen, 0, 0, 100, 100)

END SUB
' ========================================================================================

' ========================================================================================
' Main
' ========================================================================================
FUNCTION wWinMain (BYVAL hInstance AS HINSTANCE, _
                   BYVAL hPrevInstance AS HINSTANCE, _
                   BYVAL pwszCmdLine AS WSTRING PTR, _
                   BYVAL nCmdShow AS LONG) AS LONG

   ' // Set process DPI aware
   SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE)
   ' // Enable visual styles without including a manifest file
   AfxEnableVisualStyles

   ' // Create the main window
   DIM pWindow AS CWindow = "MyClassName"
   pWindow.Create(NULL, "GDI+ Gdip_CreateAdjustableArrowCap", @WndProc)
   ' // Size it by setting the wanted width and height of its client area
   pWindow.SetClientSize(400, 250)
   ' // Center the window
   pWindow.Center

   ' // Add a graphic control
   DIM pGraphCtx AS CGraphCtx = CGraphCtx(@pWindow, IDC_GRCTX, "", 0, 0, pWindow.ClientWidth, pWindow.ClientHeight)
   pGraphCtx.Clear RGB_FLORALWHITE
   ' // Anchor the control
   pWindow.AnchorControl(pGraphCtx.hWindow, AFX_ANCHOR_HEIGHT_WIDTH)
   
   ' // Get the memory device context of the graphic control
   DIM hdc AS HDC = pGraphCtx.GetMemDc

   ' // Initialize GDI+
   DIM pGdiPlusObjects AS GdiPlusObjects

   ' // Draw the graphics
   Example_CreateAdjustableArrowCap(hdc)

   ' // Displays the window and dispatches the Windows messages
   FUNCTION = pWindow.DoEvents(nCmdShow)

END FUNCTION
' ========================================================================================

' ========================================================================================
' Main window procedure
' ========================================================================================
FUNCTION WndProc (BYVAL hwnd AS HWND, BYVAL uMsg AS UINT, BYVAL wParam AS WPARAM, BYVAL lParam AS LPARAM) AS LRESULT

   SELECT CASE uMsg

      ' // If an application processes this message, it should return zero to continue
      ' // creation of the window. If the application returns –1, the window is destroyed
      ' // and the CreateWindowExW function returns a NULL handle.
      CASE WM_CREATE
         AfxEnableDarkModeForWindow(hwnd)
         RETURN 0

      ' // Theme has changed
      CASE WM_THEMECHANGED
         AfxEnableDarkModeForWindow(hwnd)
         RETURN 0

      CASE WM_COMMAND
         SELECT CASE CBCTL(wParam, lParam)
            CASE IDCANCEL
               ' // If ESC key pressed, close the application by sending an WM_CLOSE message
               IF CBCTLMSG(wParam, lParam) = BN_CLICKED THEN
                  SendMessageW hwnd, WM_CLOSE, 0, 0
                  RETURN 0
               END IF
         END SELECT

        CASE WM_DESTROY
         ' // Ends the application by sending a WM_QUIT message
         PostQuitMessage(0)
         RETURN 0

   END SELECT

   ' // Default processing of Windows messages
   FUNCTION = DefWindowProcW(hwnd, uMsg, wParam, lParam)

END FUNCTION
' ========================================================================================

GdiPlusCustomLineCap

A line cap defines the style of graphic used to draw the ends of a line. It can be various shapes, such as a square, circle, or diamond. A custom line cap is defined by the path that draws it. The path is drawn by using a Pen object to draw the outline of a shape or by using a Brush object to fill the interior. The cap can be used on either or both ends of the line. Spacing can be adjusted between the end caps and the line.

' ========================================================================================
TYPE GdiPlusCustomLineCap
Public:
   m_CustomLineCap AS GpCustomLineCap PTR
   DECLARE CONSTRUCTOR (BYVAL customCap AS GpPath PTR)
   DECLARE CONSTRUCTOR (BYVAL fillPath AS GpPath PTR, BYVAL strokePath AS GpPath PTR, _
           BYVAL baseCap AS GpLineCap = LinecapFlat, BYVAL baseInset AS SINGLE = 0.0)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpCustomLineCap PTR PTR
   DECLARE OPERATOR CAST () AS GpCustomLineCap PTR
END TYPE
' ========================================================================================

' ========================================================================================
' Creates a CustomLineCap
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusCustomLineCap (BYVAL customCap AS GpPath PTR)
   IF customCap THEN SetLastError(GdipCloneCustomLineCap(customCap, @m_CustomLineCap))
END CONSTRUCTOR
' ========================================================================================

' =====================================================================================
' Creates a CustomLineCap object from a fill path and a stroke path.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusCustomLineCap (BYVAL fillPath AS GpPath PTR, BYVAL strokePath AS GpPath PTR, _
BYVAL baseCap AS GpLineCap = LinecapFlat, BYVAL baseInset AS SINGLE = 0.0)
   SetLastError(GdipCreateCustomLineCap(fillPath, strokePath, baseCap, baseinset, @m_CustomLineCap))
END CONSTRUCTOR
' =====================================================================================
' ========================================================================================
' * Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusCustomLineCap
   IF m_CustomLineCap THEN SetLastError(GdipDeleteCustomLineCap(m_CustomLineCap))
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpCustomLineCap object
' ========================================================================================
PRIVATE OPERATOR * (BYREF cap AS GdiPlusCustomLineCap) AS GpCustomLineCap PTR
   RETURN cap.m_CustomLineCap
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpCustomLineCap object
' ========================================================================================
PRIVATE OPERATOR GdiPlusCustomLineCap.@ () AS GpCustomLineCap PTR PTR
   RETURN @m_CustomLineCap
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusCustomLineCap.CAST () AS GpCustomLineCap PTR
   RETURN m_CustomLineCap
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' The following example creates a CustomLineCap object, sets its base cap, and then gets
' the base cap and assigns it to a Pen object. It then uses the Pen object to draw a line.
' ========================================================================================
SUB Example_GetBaseCap (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Create an empty Path object for the custom cap
   DIM capPath AS GdiPlusGraphicsPath = FillModeAlternate

   ' // Create a CustomLineCap using the empty path
   DIM customCap AS GdiPlusCustomLineCap = GdiPlusCustomLineCap(NULL, *capPath)

   ' // Create a red Pen with width 10
   DIM pen AS GdiPlusPen = GdiPlusPen(ARGB_RED, 10)

   ' // Assign the custom cap as the end cap of the pen
   GdipSetPenCustomEndCap(pen, customCap)

   ' // Draw a line using the pen and graphics object
   GdipDrawLine(graphics, pen, 0, 0, 100, 100)

END SUB
' ========================================================================================

GdiPlusAdjustableArrowCap

Builds a line cap that looks like an arrow.

' ========================================================================================
TYPE GdiPlusAdjustableArrowCap
Public:
   m_AdjustableArrowCap AS GpAdjustableArrowCap PTR
   DECLARE CONSTRUCTOR (BYVAL cap AS GpAdjustableArrowCap PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL nHeight AS SINGLE, BYVAL nWidth AS SINGLE, BYVAL bIsFilled AS BOOL = CTRUE)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpAdjustableArrowCap PTR PTR
   DECLARE OPERATOR CAST () AS GpAdjustableArrowCap PTR
END TYPE
' ========================================================================================

' ========================================================================================
' Creates a AdjustableArrowCap
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusAdjustableArrowCap (BYVAL cap AS GpAdjustableArrowCap PTR = NULL)
   IF cap THEN SetLastError(GdipCloneCustomLineCap(cap, @m_AdjustableArrowCap))
END CONSTRUCTOR
' ========================================================================================

' =====================================================================================
' Creates an adjustable arrow line cap with the specified height and width. The arrow
' line cap can be filled or nonfilled. The middle inset defaults to zero.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusAdjustableArrowCap (BYVAL nHeight AS SINGLE, BYVAL nWidth AS SINGLE, BYVAL bIsFilled AS BOOL = CTRUE)
   SetLastError(GdipCreateAdjustableArrowCap(nHeight, nWidth, bIsFilled, @m_AdjustableArrowCap))
END CONSTRUCTOR
' =====================================================================================
' ========================================================================================
' * Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusAdjustableArrowCap
   IF m_AdjustableArrowCap THEN SetLastError(GdipDeleteCustomLineCap(m_AdjustableArrowCap))
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpAdjustableArrowCap object
' ========================================================================================
PRIVATE OPERATOR * (BYREF cap AS GdiPlusAdjustableArrowCap) AS GpAdjustableArrowCap PTR
   RETURN cap.m_AdjustableArrowCap
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpAdjustableArrowCap object
' ========================================================================================
PRIVATE OPERATOR GdiPlusAdjustableArrowCap.@ () AS GpAdjustableArrowCap PTR PTR
   RETURN @m_AdjustableArrowCap
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusAdjustableArrowCap.CAST () AS GpAdjustableArrowCap PTR
   RETURN m_AdjustableArrowCap
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' The following example creates an AdjustableArrowCap object, myArrow, and sets the fill
' mode to TRUE. The code then creates a Pen object and assigns myArrow as the ending line
' cap for this Pen object. Next, the code tests whether myArrow is filled and, if it is,
' draws a line.
' ========================================================================================
SUB Example_IsFilled (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   DIM dpiRatio AS SINGLE = graphics.DpiRatio
   graphics.ScaleTransform(dpiRatio)

   ' // Create an AdjustableArrowCap that is filled.
   DIM myArrow AS GdiPlusAdjustableArrowCap = GdiPlusAdjustableArrowCap(10, 10, TRUE)
   ' // Adjust to DPI by setting the scale width
   GdipSetCustomLineCapWidthScale(myArrow, dpiRatio)

   ' // Create a Pen, and assign myArrow as the end cap.
   DIM arrowPen AS GdiPlusPen = GdiPlusPen(ARGB_Violet, 1)
   ' // Assign myArrow as the end cap.
   GdipSetPenCustomEndCap(arrowPen, myArrow)

   ' // If the cap is filled, draw a line using arrowPen.
   DIM isFilled AS BOOL
   GdipGetAdjustableArrowCapFillState(myArrow, @isFilled)
   IF isFilled THEN GdipDrawLine(graphics, arrowPen, 0, 0, 100, 100)

END SUB
' ========================================================================================

GdiPlusBrush

A Brush object is used to paint the interior of graphics shapes, such as rectangles, ellipses, pies, polygons, and paths.

' ========================================================================================
TYPE GdiPlusBrush
Public:
   m_Brush AS GpBrush PTR
   DECLARE CONSTRUCTOR (BYVAL brush AS GpBrush PTR = NULL)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpBrush PTR PTR
   DECLARE OPERATOR CAST () AS GpBrush PTR
END TYPE
' ========================================================================================

' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusBrush (BYVAL brush AS GpBrush PTR = NULL)
   IF brush THEN SetLastError(GdipCloneBrush(brush, @m_brush))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusBrush
   IF m_Brush THEN GdipDeleteBrush(m_Brush)
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpBrush object
' ========================================================================================
PRIVATE OPERATOR * (BYREF brush AS GdiPlusBrush) AS GpBrush PTR
   RETURN brush.m_Brush
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpBrush object
' ========================================================================================
PRIVATE OPERATOR GdiPlusBrush.@ () AS GpBrush PTR PTR
   RETURN @m_Brush
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusBrush.CAST () AS GpBrush PTR
   RETURN m_Brush
END OPERATOR
' ========================================================================================

GdiPlusSolidBrush

Defines a solid color Brush object. A Brush object is used to fill in shapes similar to the way a paint brush can paint the inside of a shape.

' ========================================================================================
TYPE GdiPlusSolidBrush
Public:
   m_Brush AS GpSolidBrush PTR
   DECLARE CONSTRUCTOR (BYVAL brush AS GpSolidBrush PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL colour AS ARGB = &hFF000000)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpSolidBrush PTR PTR
   DECLARE OPERATOR CAST () AS GpSolidBrush PTR
END TYPE
' ========================================================================================

' ========================================================================================
' Creates a brush from another brush.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusSolidBrush (BYVAL brush AS GpSolidBrush PTR = NULL)
   IF brush THEN SetLastError(GdipCloneBrush(brush, @m_brush))
END CONSTRUCTOR
' ========================================================================================

' ========================================================================================
' Creates a solid brush filled with the specified color.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusSolidBrush (BYVAL colour AS ARGB = &hFF000000)
   SetLastError(GdipCreateSolidFill(colour, @m_Brush))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusSolidBrush
   IF m_Brush THEN GdipDeleteBrush(m_Brush)
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpSolidBrush object
' ========================================================================================
PRIVATE OPERATOR * (BYREF brush AS GdiPlusSolidBrush) AS GpSolidBrush PTR
   RETURN brush.m_Brush
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpBrush object
' ========================================================================================
PRIVATE OPERATOR GdiPlusSolidBrush.@ () AS GpSolidBrush PTR PTR
   RETURN @m_Brush
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusSolidBrush.CAST () AS GpSolidBrush PTR
   RETURN m_Brush
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' The following example creates a SolidBrush object, clones it, and then uses the clone
' to fill a rectangle.
' ========================================================================================
SUB Example_CloneBrush (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Create a SolidBrush
   DIM brush AS GdiPlusSolidBrush = ARGB_RED

   ' // Create a clone of the SolidBrush
   DIM cloneBrush AS GdiPlusSolidBrush = *brush

   ' // Use the clone brush to fill a rectagle
   GdipFillRectangle(graphics, cloneBrush, 0, 0, 100, 100)

END SUB
' ========================================================================================

GdiPlusHatchBrush

An HatchBrush defines a rectangular brush with a hatch style, a foreground color, and a background color. There are six hatch styles. The foreground color defines the color of the hatch lines; the background color defines the color over which the hatch lines are drawn

' ========================================================================================
TYPE GdiPlusHatchBrush
Public:
   m_Brush AS GpHatchBrush PTR
   DECLARE CONSTRUCTOR (BYVAL brush AS GpHatchBrush PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL nHatchStyle AS HatchStyle, BYVAL foreColor AS ARGB, BYVAL backColor AS ARGB = &HFF000000)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpHatchBrush PTR PTR
   DECLARE OPERATOR CAST () AS GpHatchBrush PTR
END TYPE
' ========================================================================================

' ========================================================================================
' Creates a brush from another brush.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusHatchBrush (BYVAL brush AS GpHatchBrush PTR = NULL)
   IF brush THEN SetLastError(GdipCloneBrush(brush, @m_brush))
END CONSTRUCTOR
' ========================================================================================
' =====================================================================================
' Creates a HatchBrush object based on a hatch style, a foreground color, and a background color.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusHatchBrush (BYVAL nHatchStyle AS HatchStyle, BYVAL foreColor AS ARGB, BYVAL backColor AS ARGB = &HFF000000)
   SetLastError(GdipCreateHatchBrush(nHatchStyle, foreColor, backColor, @m_brush))
END CONSTRUCTOR
' =====================================================================================
' ========================================================================================
' Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusHatchBrush
   IF m_Brush THEN GdipDeleteBrush(m_Brush)
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpHatchBrush object
' ========================================================================================
PRIVATE OPERATOR * (BYREF brush AS GdiPlusHatchBrush) AS GpHatchBrush PTR
   RETURN brush.m_Brush
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpHatchBrush object
' ========================================================================================
PRIVATE OPERATOR GdiPlusHatchBrush.@ () AS GpHatchBrush PTR PTR
   RETURN @m_Brush
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusHatchBrush.CAST () AS GpHatchBrush PTR
   RETURN m_Brush
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' The following example draws six of the available hatch styles.
' ========================================================================================
SUB Example_CreateHatchBrush (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Set and then draw the first hatch style.
   DIM brush AS GdiPlusHatchBrush = GdiPlusHatchBrush(HatchStyleHorizontal, ARGB_BLACK, ARGB_WHITE)
   GdipFillRectangle(graphics, brush, 20, 20, 115, 50)

   ' // Set and then draw the second hatch style.
   DIM brush1 AS GdiPlusHatchBrush = GdiPlusHatchBrush(HatchStyleVertical, ARGB_BLACK, ARGB_WHITE)
   GdipFillRectangle(graphics, brush1, 145, 20, 115, 50)

   ' // Set and then draw the third hatch style.
   DIM brush2 AS GdiPlusHatchBrush = GdiPlusHatchBrush(HatchStyleForwardDiagonal, ARGB_BLACK, ARGB_WHITE)
   GdipFillRectangle(graphics, brush2, 270, 20, 115, 50)

   ' // Set and then draw the fourth hatch style.
   DIM brush3 AS GdiPlusHatchBrush = GdiPlusHatchBrush(HatchStyleBackwardDiagonal, ARGB_BLACK, ARGB_WHITE)
   GdipFillRectangle(graphics, brush3, 20, 100, 115, 50)

   ' // Set and then draw the fifth hatch style.
   DIM brush4 AS GdiPlusHatchBrush = GdiPlusHatchBrush(HatchStyleCross, ARGB_BLACK, ARGB_WHITE)
   GdipFillRectangle(graphics, brush4, 145, 100, 115, 50)

   ' // Set and then draw the sixth hatch style.
   DIM brush5 AS GdiPlusHatchBrush = GdiPlusHatchBrush(HatchStyleDiagonalCross, ARGB_BLACK, ARGB_WHITE)
   GdipFillRectangle(graphics, brush5, 270, 100, 115, 50)

END SUB
' ========================================================================================

GdiPlusLinearGradientBrush

The LinearGradientBrush functions allow to paint a color gradient in which the color changes evenly from the starting boundary line of the linear gradient brush to the ending boundary line of the linear gradient brush. The boundary lines of a linear gradient brush are two parallel straight lines. The color gradient is perpendicular to the boundary lines of the linear gradient brush, changing gradually across the stroke from the starting boundary line to the ending boundary line. The color gradient has one color at the starting boundary line and another color at the ending boundary line.

' ========================================================================================
TYPE GdiPlusLinearGradientBrush
Public:
   m_Brush AS GpLinearGradientBrush PTR
   DECLARE CONSTRUCTOR (BYVAL point1 AS GpPointF PTR, BYVAL point2 AS GpPointF PTR, BYVAL color1 AS ARGB, BYVAL color2 AS ARGB, BYVAL wrap AS WrapMode = WrapModeTile)
   DECLARE CONSTRUCTOR (BYVAL point1 AS GpPoint PTR, BYVAL point2 AS GpPoint PTR, BYVAL color1 AS ARGB, BYVAL color2 AS ARGB, BYVAL wrap AS WrapMode = WrapModeTile)
   DECLARE CONSTRUCTOR (BYVAL rc AS GpRectF PTR, BYVAL color1 AS ARGB, BYVAL color2 AS ARGB, BYVAL nMode AS LinearGradientMode, BYVAL wrap AS WrapMode = WrapModeTile)
   DECLARE CONSTRUCTOR (BYVAL rc AS GpRect PTR, BYVAL color1 AS ARGB, BYVAL color2 AS ARGB, BYVAL nMode AS LinearGradientMode, BYVAL wrap AS WrapMode = WrapModeTile)
   DECLARE CONSTRUCTOR (BYVAL rc AS GpRectF PTR, BYVAL color1 AS ARGB, BYVAL color2 AS ARGB, BYVAL angle AS SINGLE, BYVAL isAngleScalable AS BOOL, BYVAL wrap AS WrapMode = WrapModeTile)
   DECLARE CONSTRUCTOR (BYVAL rc AS GpRect PTR, BYVAL color1 AS ARGB, BYVAL color2 AS ARGB, BYVAL angle AS SINGLE, BYVAL isAngleScalable AS BOOL, BYVAL wrap AS WrapMode = WrapModeTile)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpLinearGradientBrush PTR PTR
   DECLARE OPERATOR CAST () AS GpLinearGradientBrush PTR
END TYPE
' ========================================================================================

' =====================================================================================
' Creates a LinearGradientBrush object from a set of boundary points and boundary colors.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusLinearGradientBrush (BYVAL point1 AS GpPointF PTR, BYVAL point2 AS GpPointF PTR, BYVAL color1 AS ARGB, BYVAL color2 AS ARGB, BYVAL wrap AS WrapMode = WrapModeTile)
   SetLastError(GdipCreateLineBrush(point1, point2, color1, color2, wrap, @m_brush))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusLinearGradientBrush (BYVAL point1 AS GpPoint PTR, BYVAL point2 AS GpPoint PTR, BYVAL color1 AS ARGB, BYVAL color2 AS ARGB, BYVAL wrap AS WrapMode = WrapModeTile)
   SetLastError(GdipCreateLineBrushI(point1, point2, color1, color2, wrap, @m_brush))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
' Creates a LinearGradientBrush object from a set of boundary points and boundary colors.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusLinearGradientBrush (BYVAL rc AS GpRectF PTR, BYVAL color1 AS ARGB, BYVAL color2 AS ARGB, BYVAL nMode AS LinearGradientMode, BYVAL wrap AS WrapMode = WrapModeTile)
   SetLastError(GdipCreateLineBrushFromRect(rc, color1, color2, nMode, wrap, @m_brush))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusLinearGradientBrush (BYVAL rc AS GpRect PTR, BYVAL color1 AS ARGB, BYVAL color2 AS ARGB, BYVAL nMode AS LinearGradientMode, BYVAL wrap AS WrapMode = WrapModeTile)
   SetLastError(GdipCreateLineBrushFromRectI(rc, color1, color2, nMode, wrap, @m_brush))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
' Creates a LinearGradientBrush object from a set of boundary points and boundary colors.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusLinearGradientBrush (BYVAL rc AS GpRectF PTR, BYVAL color1 AS ARGB, BYVAL color2 AS ARGB, BYVAL angle AS SINGLE, BYVAL isAngleScalable AS BOOL, BYVAL wrap AS WrapMode = WrapModeTile)
   SetLastError(GdipCreateLineBrushFromRectWithAngle(rc, color1, color2, angle, isAngleScalable, wrap, @m_brush))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusLinearGradientBrush (BYVAL rc AS GpRect PTR, BYVAL color1 AS ARGB, BYVAL color2 AS ARGB, BYVAL angle AS SINGLE, BYVAL isAngleScalable AS BOOL, BYVAL wrap AS WrapMode = WrapModeTile)
   SetLastError(GdipCreateLineBrushFromRectWithAngleI(rc, color1, color2, angle, isAngleScalable, wrap, @m_brush))
END CONSTRUCTOR
' =====================================================================================
' ========================================================================================
' Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusLinearGradientBrush
   IF m_Brush THEN GdipDeleteBrush(m_Brush)
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpLinearGradientBrush object
' ========================================================================================
PRIVATE OPERATOR * (BYREF brush AS GdiPlusLinearGradientBrush) AS GpLinearGradientBrush PTR
   RETURN brush.m_Brush
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpLinearGradientBrush object
' ========================================================================================
PRIVATE OPERATOR GdiPlusLinearGradientBrush.@ () AS GpLinearGradientBrush PTR PTR
   RETURN @m_Brush
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusLinearGradientBrush.CAST () AS GpLinearGradientBrush PTR
   RETURN m_Brush
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' Creates a LinearGradientBrush object from a set of boundary points and boundary colors.
' This function is ideal for creating gradients aligned to rectangular UI elements or backgrounds.
' ========================================================================================
SUB Example_CreateLineBrushFromRect (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Define gradient rectangle
   DIM rcf AS GpRectF = (0, 0, 200, 100)

   ' // Create brush with horizontal gradient
   DIM brush AS GdiPlusLinearGradientBrush = GdiPlusLinearGradientBrush(@rcf, ARGB_RED, ARGB_BLUE, LinearGradientModeHorizontal)

   ' // Fill rectangle
   GdipFillRectangle(graphics, brush, rcf.x, rcf.y, rcf.Width, rcf.Height)

END SUB
' ========================================================================================

GdiPlusPathGradientBrush

The PathGradientBrush functions allow to set the attributes of a color gradient that you can use to fill the interior of a path with a gradually changing color. A path gradient brush has a boundary path, a boundary color, a center point, and a center color. When you paint an area with a path gradient brush, the color changes gradually from the boundary color to the center color as you move from the boundary path to the center point.

' ========================================================================================
TYPE GdiPlusPathGradientBrush
Public:
   m_Brush AS GpPathGradientBrush PTR
   DECLARE CONSTRUCTOR (BYVAL path AS GpPath PTR)
   DECLARE CONSTRUCTOR (BYVAL points AS CONST GpPointF PTR, BYVAL count AS INT_, BYVAL wrapMode AS GpWrapMode = WrapModeClamp)
   DECLARE CONSTRUCTOR (BYVAL points AS CONST GpPoint PTR, BYVAL count AS INT_, BYVAL wrapMode AS GpWrapMode = WrapModeClamp)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpPathGradientBrush PTR PTR
   DECLARE OPERATOR CAST () AS GpPathGradientBrush PTR
END TYPE
' ========================================================================================

' =====================================================================================
' Creates a path gradient brush from a path
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusPathGradientBrush (BYVAL path AS GpPath PTR)
   SetLastError(GdipCreatePathGradientFromPath(path, @m_brush))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
' Creates a path gradient brush
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusPathGradientBrush (BYVAL points AS CONST GpPointF PTR, BYVAL count AS INT_, BYVAL wrapMode AS GpWrapMode = WrapModeClamp)
   SetLastError(GdipCreatePathGradient(points, count, wrapMode, @m_brush))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusPathGradientBrush (BYVAL points AS CONST GpPoint PTR, BYVAL count AS INT_, BYVAL wrapMode AS GpWrapMode = WrapModeClamp)
   SetLastError(GdipCreatePathGradientI(points, count, wrapMode, @m_brush))
END CONSTRUCTOR
' =====================================================================================
' ========================================================================================
' Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusPathGradientBrush
   IF m_Brush THEN GdipDeleteBrush(m_Brush)
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpPathGradientBrush object
' ========================================================================================
PRIVATE OPERATOR * (BYREF brush AS GdiPlusPathGradientBrush) AS GpPathGradientBrush PTR
   RETURN brush.m_Brush
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpPathGradientBrush object
' ========================================================================================
PRIVATE OPERATOR GdiPlusPathGradientBrush.@ () AS GpPathGradientBrush PTR PTR
   RETURN @m_Brush
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusPathGradientBrush.CAST () AS GpPathGradientBrush PTR
   RETURN m_Brush
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' The following example draws a star-shaped GraphicsPath.
' Creates a star-shaped GraphicsPath and fills it using a PathGradientBrush constructed
' from that path. The gradient transitions from a red center to a set of surround colors
' defined at each vertex of the star. DPI scaling is applied globally to ensure consistent
' rendering across high-resolution displays.
' ========================================================================================
SUB Example_CreatePathGradientFromPath (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Create a GraphicsPath object and initializes the fill mode.
   DIM path AS GdiPlusGraphicsPath = FillModeAlternate

   ' // Fill the array of points.
   DIM pts(0 TO 9) AS GpPointF
   pts(0).x = 75  : pts(0).y = 0
   pts(1).x = 100 : pts(1).y = 50
   pts(2).x = 150 : pts(2).y = 50
   pts(3).x = 112 : pts(3).y = 75
   pts(4).x = 150 : pts(4).y = 150
   pts(5).x = 75  : pts(5).y = 100
   pts(6).x = 0   : pts(6).y = 150
   pts(7).x = 37  : pts(7).y = 75
   pts(8).x = 0   : pts(8).y = 50
   pts(9).x = 50  : pts(9).y = 50

   ' // Construct the path with the array of points.
   GdipAddPathLine2(path, @pts(0), 10)

   ' // Use the path to construct a path gradient brush.
   DIM brush AS GdiPlusPathGradientBrush = *path

   ' // Set the color at the center of the path to red.
   GdipSetPathGradientCenterColor(brush, ARGB_RED)

   ' // Set the colors of the points in the array.
   DIM Colors(9) AS ARGB
   Colors(0) = ARGB_BLACK
   Colors(1) = ARGB_LIGHTGREEN
   Colors(2) = ARGB_BLUE
   Colors(3) = ARGB_WHITE
   Colors(4) = ARGB_BLACK
   Colors(5) = ARGB_LIGHTGREEN
   Colors(6) = ARGB_BLUE
   Colors(7) = ARGB_WHITE
   Colors(8) = ARGB_BLACK
   Colors(9) = ARGB_LIGHTGREEN
   DIM count AS LONG = 10
   GdipSetPathGradientSurroundColorsWithCount(brush, @Colors(0), @count)

   ' // Fill the path with the path gradient brush.
   GdipFillPath(graphics, brush, path)

END SUB
' ========================================================================================

GdiPlusTextureBrush

The TextureBrush object is a Brush object that contains an Image object that is used for the fill. The fill image can be transformed by using the local Matrix object contained in the Brush object.

' ========================================================================================
TYPE GdiPlusTextureBrush
Public:
   m_Texture AS GpTextureBrush PTR
   DECLARE CONSTRUCTOR (BYVAL image AS GpImage PTR, BYVAL nWrapMode AS WrapMode = WrapModeTile)
   DECLARE CONSTRUCTOR (BYVAL image AS GpImage PTR, BYVAL dstRect AS GpRectF PTR, BYVAL imageAttributes AS GpImageAttributes PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL image AS GpImage PTR, BYVAL dstRect AS GpRect PTR, BYVAL imageAttributes AS GpImageAttributes PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL image AS GpImage PTR, BYVAL dstX AS SINGLE, BYVAL dstY AS SINGLE, BYVAL dstWidth AS SINGLE, BYVAL dstHeight AS SINGLE, BYVAL imageAttributes AS GpImageAttributes PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL image AS GpImage PTR, BYVAL dstX AS INT_, BYVAL dstY AS INT_, BYVAL dstWidth AS INT_, BYVAL dstHeight AS INT_, BYVAL imageAttributes AS GpImageAttributes PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL image AS GpImage PTR, BYVAL nWrapMode AS WrapMode, BYVAL dstRect AS GpRect PTR)
   DECLARE CONSTRUCTOR (BYVAL image AS GpImage PTR, BYVAL nWrapMode AS WrapMode, BYVAL dstRect AS GpRectF PTR)
   DECLARE CONSTRUCTOR (BYVAL image AS GpImage PTR, BYVAL nWrapMode AS WrapMode, BYVAL dstX AS SINGLE, BYVAL dstY AS SINGLE, BYVAL dstWidth AS SINGLE, BYVAL dstHeight AS SINGLE)
   DECLARE CONSTRUCTOR (BYVAL image AS GpImage PTR, BYVAL nWrapMode AS WrapMode, BYVAL dstX AS INT_, BYVAL dstY AS INT_, BYVAL dstWidth AS INT_, BYVAL dstHeight AS INT_)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpTextureBrush PTR PTR
   DECLARE OPERATOR CAST () AS GpTextureBrush PTR
END TYPE
' ========================================================================================

' =====================================================================================
' Creates a TextureBrush object based on an image and a wrap mode. The size of the brush
' defaults to the size of the image, so the entire image is used by the brush.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusTextureBrush (BYVAL image AS GpImage PTR, BYVAL nWrapMode AS WrapMode = WrapModeTile)
   SetLastError(GdipCreateTexture(image, nWrapmode, @m_Texture))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
' Creates a TextureBrush object based on an image, a defining set of coordinates, and
' a set of image properties.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusTextureBrush (BYVAL image AS GpImage PTR, BYVAL dstRect AS GpRectF PTR, BYVAL imageAttributes AS GpImageAttributes PTR = NULL)
   SetLastError(GdipCreateTextureIA(image, imageAttributes, dstRect->x, dstRect->y, dstRect->Width, dstRect->Height, @m_Texture))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusTextureBrush (BYVAL image AS GpImage PTR, BYVAL dstRect AS GpRect PTR, BYVAL imageAttributes AS GpImageAttributes PTR = NULL)
   SetLastError(GdipCreateTextureIAI(image, imageAttributes, dstRect->x, dstRect->y, dstRect->Width, dstRect->Height, @m_Texture))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusTextureBrush (BYVAL image AS GpImage PTR, BYVAL dstX AS SINGLE, BYVAL dstY AS SINGLE, BYVAL dstWidth AS SINGLE, BYVAL dstHeight AS SINGLE, BYVAL imageAttributes AS GpImageAttributes PTR = NULL)
   SetLastError(GdipCreateTextureIA(image, imageAttributes, dstX, dstY, dstWidth, dstHeight, @m_Texture))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusTextureBrush (BYVAL image AS GpImage PTR, BYVAL dstX AS INT_, BYVAL dstY AS INT_, BYVAL dstWidth AS INT_, BYVAL dstHeight AS INT_, BYVAL imageAttributes AS GpImageAttributes PTR = NULL)
   SetLastError(GdipCreateTextureIA(image, imageAttributes, dstX, dstY, dstWidth, dstHeight, @m_Texture))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
' Creates a TextureBrush object based on an image, a wrap mode, and a defining set of coordinates.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusTextureBrush (BYVAL image AS GpImage PTR, BYVAL nWrapMode AS WrapMode, BYVAL dstRect AS GpRect PTR)
   SetLastError(GdipCreateTexture2I(image, nWrapMode, dstRect->x, dstRect->y, dstRect->Width, dstRect->Height, @m_Texture))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusTextureBrush (BYVAL image AS GpImage PTR, BYVAL nWrapMode AS WrapMode, BYVAL dstRect AS GpRectF PTR)
   SetLastError(GdipCreateTexture2(image, nWrapMode, dstRect->x, dstRect->y, dstRect->Width, dstRect->Height, @m_Texture))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusTextureBrush (BYVAL image AS GpImage PTR, BYVAL nWrapMode AS WrapMode, BYVAL dstX AS SINGLE, BYVAL dstY AS SINGLE, BYVAL dstWidth AS SINGLE, BYVAL dstHeight AS SINGLE)
   SetLastError(GdipCreateTexture2(image, nWrapMode, dstX, dstY, dstWidth, dstHeight, @m_Texture))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusTextureBrush (BYVAL image AS GpImage PTR, BYVAL nWrapMode AS WrapMode, BYVAL dstX AS INT_, BYVAL dstY AS INT_, BYVAL dstWidth AS INT_, BYVAL dstHeight AS INT_)
   SetLastError(GdipCreateTexture2I(image, nWrapMode, dstX, dstY, dstWidth, dstHeight, @m_Texture))
END CONSTRUCTOR
' =====================================================================================
' ========================================================================================
' Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusTextureBrush
   IF m_Texture THEN GdipDeleteBrush(m_Texture)
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpTextureBrush object
' ========================================================================================
PRIVATE OPERATOR * (BYREF texture AS GdiPlusTextureBrush) AS GpTextureBrush PTR
   RETURN texture.m_Texture
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpTextureBrush object
' ========================================================================================
PRIVATE OPERATOR GdiPlusTextureBrush.@ () AS GpTextureBrush PTR PTR
   RETURN @m_Texture
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusTextureBrush.CAST () AS GpTextureBrush PTR
   RETURN m_Texture
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' The following example creates a texture brush and fills a rectangle.
' ========================================================================================
SUB Example_CreateTexture (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Load the image and set the dpi resolution
   DIM image AS GdiPlusImage = "HouseAndTree.gif"
   image.SetResolution(graphics)

   ' // Create a texture brush, and set its wrap mode.
   DIM textureBrush AS GdiPlusTextureBrush = *image
   ' // Fill a rectangle with the texture brush
   GdipFillRectangle(graphics, textureBrush, 20, 20, 360, 210)

END SUB
' ========================================================================================

GdiPlusImage

The Image functions allow loading and saving raster images (bitmaps) and vector images (metafiles). An Image object encapsulates a bitmap or a metafile and stores attributes that you can retrieve by calling various Get functions. You can construct Image objects from a variety of file types including BMP, ICON, GIF, JPEG, Exif, PNG, TIFF, WMF, and EMF.

' ========================================================================================
TYPE GdiPlusImage
Public:
   m_Image AS GpImage PTR
   DECLARE CONSTRUCTOR (BYVAL image AS GpImage PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL pwszFileName AS WSTRING PTR, BYVAL useEmbeddedColorManagement AS BOOLEAN = FALSE)
   DECLARE CONSTRUCTOR (BYVAL stream AS IStream PTR, BYVAL useEmbeddedColorManagement AS BOOLEAN = FALSE)
   DECLARE CONSTRUCTOR (BYVAL hInst AS HINSTANCE, BYREF wszImageName AS WSTRING)
   DECLARE OPERATOR CAST () AS GpImage PTR
   DECLARE OPERATOR @ () AS GpImage PTR PTR
   DECLARE DESTRUCTOR
   DECLARE SUB SetResolution (BYVAL graphics AS GpGraphics PTR, BYVAL dpiX AS SINGLE = 0, BYVAL dpiY AS SINGLE = 0)
END TYPE
' ========================================================================================

' ========================================================================================
' Creates and initializes an Image object from another Image object.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusImage (BYVAL image AS GpImage PTR)
   IF image THEN SetLastError(GdipCloneImage(image, @m_Image))
END CONSTRUCTOR
' ========================================================================================

' ========================================================================================
' Creates an Image object based on a file.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusImage (BYVAL pwszFileName AS WSTRING PTR, BYVAL useEmbeddedColorManagement AS BOOLEAN = FALSE)
   IF useEmbeddedColorManagement THEN
      SetLastError(GdipLoadImageFromFileICM(pwszFileName, @m_Image))
   ELSE
      SetLastError(GdipLoadImageFromFile(pwszFileName, @m_Image))
   END IF
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates an Image object based on a stream.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusImage (BYVAL stream AS IStream PTR, BYVAL useEmbeddedColorManagement AS BOOLEAN = FALSE)
   IF useEmbeddedColorManagement THEN
      SetLastError(GdipLoadImageFromStreamICM(stream, @m_Image))
   ELSE
      SetLastError(GdipLoadImageFromStream(stream, @m_Image))
   END IF
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates an Image object from a resource file.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusImage (BYVAL hInst AS HINSTANCE, BYREF wszImageName AS WSTRING)
   DIM stream AS IStream PTR = AfxImageStreamFromRes(hInst, wszImageName)
   IF stream = NULL THEN SetLastError(InvalidParameter): EXIT CONSTRUCTOR
   SetLastError(GdipLoadImageFromStream(stream, @m_Image))
   stream->lpVtbl->Release(stream)
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' * Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusImage
   IF m_Image THEN SetLastError(GdipDisposeImage(m_Image))
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpImage object
' ========================================================================================
PRIVATE OPERATOR * (BYREF img AS GdiPlusImage) AS GpImage PTR
   RETURN img.m_Image
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusImage.CAST () AS GpImage PTR
   RETURN m_Image
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpImage object
' ========================================================================================
PRIVATE OPERATOR GdiPlusImage.@ () AS GpImage PTR PTR
   RETURN @m_Image
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE SUB GdiPlusImage.SetResolution (BYVAL graphics AS GpGraphics PTR, BYVAL dpiX AS SINGLE = 0, BYVAL dpiY AS SINGLE = 0)
   IF dpiX = 0 AND dpiY = 0 THEN
      GdipGetDpiX(graphics, @dpiX)
      GdipGetDpiY(graphics, @dpiY)
   END IF
   SetLastError(GdipBitmapSetResolution(m_Image, dpiX, dpiY))
END SUB
' ========================================================================================

Example

' ========================================================================================
' The following example creates an Image object based on a JPEG file. The code creates a
' second Image object by cloning the first. Then the code calls the DrawImage method twice
' to draw the two images.
' ========================================================================================
SUB Example_CloneImage (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Load the original image from file
   DIM image1 AS GdiPlusImage = "climber.jpg"
   ' // Set the resolution of this Image object to the user's DPI settings
   image1.SetResolution(graphics)

   ' // Clone the image
   DIM image2 AS GdiPlusImage = image1

   ' // Draw the original image
   GdipDrawImage(graphics, image1, 10, 10)

   ' // Draw the cloned image
   GdipDrawImage(graphics, image2, 210, 10)

END SUB
' ========================================================================================

GdiPlusBitmap

The Bitmap functions expands on the capabilities of the Image functions by providing additional methods for creating and manipulating raster images.

' ========================================================================================
TYPE GdiPlusBitmap
Public:
   m_Bitmap AS GpBitmap PTR
   DECLARE CONSTRUCTOR (BYVAL bmp AS GpBitmap PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL x AS REAL, BYVAL y AS REAL, BYVAL nWidth AS REAL, BYVAL nHeight AS REAL, _
           BYVAL pxFormat AS PixelFormat, BYVAL srcBitmap AS GpBitmap PTR)
   DECLARE CONSTRUCTOR (BYVAL rcf AS GpRectF PTR, BYVAL pxFormat AS PixelFormat, BYVAL srcBitmap AS GpBitmap PTR)
   DECLARE CONSTRUCTOR (BYVAL pwszFileName AS WSTRING PTR, BYVAL useEmbeddedColorManagement AS BOOLEAN = FALSE)
   DECLARE CONSTRUCTOR (BYVAL stream AS IStream PTR, BYVAL useEmbeddedColorManagement AS BOOLEAN = FALSE)
   DECLARE CONSTRUCTOR (BYVAL nWidth AS INT_, BYVAL nHeight AS INT_, BYVAL stride AS INT_, BYVAL pxFormat AS PixelFormat, BYVAL scan0 AS UBYTE PTR)
   DECLARE CONSTRUCTOR (BYVAL nWidth AS INT_, BYVAL nHeight AS INT_, BYVAL pxFormat AS PixelFormat)
   DECLARE CONSTRUCTOR (BYVAL nWidth AS LONG, BYVAL nHeight AS LONG, BYVAL pTarget AS GpGraphics PTR)
   #ifdef IDirectDrawSurface7
   DECLARE CONSTRUCTOR (BYVAL surface AS IDirectDrawSurface7 PTR)
   #endif
   DECLARE CONSTRUCTOR (BYVAL gdiBitmapInfo AS BITMAPINFO PTR, BYVAL gdiBitmapData AS ANY PTR)
   DECLARE CONSTRUCTOR (BYVAL hbm AS HBITMAP, BYVAL hPal AS HPALETTE)
   DECLARE CONSTRUCTOR (BYVAL hicon AS HICON)
   DECLARE CONSTRUCTOR (BYVAL hInstance AS HINSTANCE, BYVAL pwszBitmapName AS WSTRING PTR)
   DECLARE CONSTRUCTOR (BYVAL inputBitmap AS GpBitmap PTR, BYVAL effect AS GpEffect PTR)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpBitmap PTR PTR
   DECLARE OPERATOR CAST () AS GpBitmap PTR
   DECLARE SUB SetResolution (BYVAL graphics AS GpGraphics PTR, BYVAL dpiX AS SINGLE = 0, BYVAL dpiY AS SINGLE = 0)
END TYPE
' ========================================================================================

' ========================================================================================
' Creates and initializes a Bitmap object from another Bitmap object.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL bmp AS GpBitmap PTR = NULL)
   IF bmp THEN SetLastError(GdipCloneImage(bmp, @m_Bitmap))
END CONSTRUCTOR
' ========================================================================================
' =====================================================================================
' Creates a new Bitmap object by copying a portion of the specified bitmap.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL x AS REAL, BYVAL y AS REAL, BYVAL nWidth AS REAL, BYVAL nHeight AS REAL, _
BYVAL pxFormat AS PixelFormat, BYVAL srcBitmap AS GpBitmap PTR)
   SetLastError(GdipCloneBitmapArea(x, y, nWidth, nHeight, pxFormat, srcBitmap, @m_Bitmap))
END CONSTRUCTOR
' ========================================================================================
' =====================================================================================
' Creates a new Bitmap object by copying a portion of the specified bitmap.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL rcf AS GpRectF PTR, BYVAL pxFormat AS PixelFormat, BYVAL srcBitmap AS GpBitmap PTR)
   SetLastError(GdipCloneBitmapArea(rcf->x, rcf->y, rcf->Width, rcf->Height, pxFormat, srcBitmap, @m_Bitmap))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates an Bitmap object based on a file.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL pwszFileName AS WSTRING PTR, BYVAL useEmbeddedColorManagement AS BOOLEAN = FALSE)
   IF useEmbeddedColorManagement THEN
      SetLastError(GdipCreateBitmapFromFileICM(pwszFileName, @m_Bitmap))
   ELSE
      SetLastError(GdipCreateBitmapFromFile(pwszFileName, @m_Bitmap))
   END IF
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates an Image object based on a stream.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL stream AS IStream PTR, BYVAL useEmbeddedColorManagement AS BOOLEAN = FALSE)
   IF useEmbeddedColorManagement THEN
      SetLastError(GdipCreateBitmapFromStream(stream, @m_Bitmap))
   ELSE
      SetLastError(GdipCreateBitmapFromStream(stream, @m_Bitmap))
   END IF
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates a Bitmap object based on an array of bytes along with size and format information.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL nWidth AS INT_, BYVAL nHeight AS INT_, BYVAL stride AS INT_, BYVAL pxFormat AS PixelFormat, BYVAL scan0 AS UBYTE PTR)
   SetLastError(GdipCreateBitmapFromScan0(nWidth, nHeight, stride, pxFormat, scan0, @m_Bitmap))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates a Bitmap object based on size and format information.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL nWidth AS INT_, BYVAL nHeight AS INT_, BYVAL pxFormat AS PixelFormat)
   SetLastError(GdipCreateBitmapFromScan0(nWidth, nHeight, 0, pxFormat, NULL, @m_Bitmap))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates a Bitmap object based on a Graphics object, a width, and a height.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL nWidth AS LONG, BYVAL nHeight AS LONG, BYVAL pTarget AS GpGraphics PTR)
   SetLastError(GdipCreateBitmapFromGraphics(nWidth, nHeight, pTarget, @m_Bitmap))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates a Bitmap object based on a DirectDraw surface. The Bitmap object maintains a
' reference to the DirectDraw surface until the Bitmap object is deleted or goes out of scope.
' ========================================================================================
#ifdef IDirectDrawSurface7
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL surface AS IDirectDrawSurface7 PTR)
   SetLastError(GdipCreateBitmapFromDirectDrawSurface(surface, @m_Bitmap))
END CONSTRUCTOR
#endif
' ========================================================================================
' ========================================================================================
' Creates a Bitmap object based on a BITMAPINFO structure and an array of pixel data.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL gdiBitmapInfo AS BITMAPINFO PTR, BYVAL gdiBitmapData AS ANY PTR)
   SetLastError(GdipCreateBitmapFromGdiDib(gdiBitmapInfo, gdiBitmapData, @m_Bitmap))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates a Bitmap object based on a handle to a Windows Windows Graphics Device
' Interface (GDI) bitmap and a handle to a GDI palette.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL hbm AS HBITMAP, BYVAL hPal AS HPALETTE)
   SetLastError(GdipCreateBitmapFromHBITMAP(hbm, hpal, @m_Bitmap))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates a Bitmap object based on an icon.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL hicon AS HICON)
   SetLastError(GdipCreateBitmapFromHICON(hicon, @m_Bitmap))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates a Bitmap object based on an application or DLL instance handle and the name of a bitmap.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL hInstance AS HINSTANCE, BYVAL pwszBitmapName AS WSTRING PTR)
   SetLastError(GdipCreateBitmapFromResource(hInstance, pwszBitmapName, @m_Bitmap))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates a new Bitmap object by applying a specified effect to an existing Bitmap object.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusBitmap (BYVAL inputBitmap AS GpBitmap PTR, BYVAL effect AS GpEffect PTR)
   SetLastError(GdipBitmapCreateApplyEffect(@inputBitmap, 1, effect, NULL, NULL, @m_Bitmap, FALSE, NULL, NULL))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' * Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusBitmap
   IF m_Bitmap THEN SetLastError(GdipDisposeImage(m_Bitmap))
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpBitmap object
' ========================================================================================
PRIVATE OPERATOR * (BYREF bmp AS GdiPlusBitmap) AS GpBitmap PTR
   RETURN bmp.m_Bitmap
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpBitmap object
' ========================================================================================
PRIVATE OPERATOR GdiPlusBitmap.@ () AS GpBitmap PTR PTR
   RETURN @m_Bitmap
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusBitmap.CAST () AS GpBitmap PTR
   RETURN m_Bitmap
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE SUB GdiPlusBitmap.SetResolution (BYVAL graphics AS GpGraphics PTR, BYVAL dpiX AS SINGLE = 0, BYVAL dpiY AS SINGLE = 0)
   IF dpiX = 0 AND dpiY = 0 THEN
      GdipGetDpiX(graphics, @dpiX)
      GdipGetDpiY(graphics, @dpiY)
   END IF
   SetLastError(GdipBitmapSetResolution(m_Bitmap, dpiX, dpiY))
END SUB
' ========================================================================================

Example

' ========================================================================================
' The following example creates a Bitmap object based on a JPEG file and draws it.
' ========================================================================================
SUB Example_CreateBitmap (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Create a bitmap object from a .jpg file
   DIM myBitmap AS GdiPlusBitmap = "climber.jpg"
   ' // Set the resolution of this Bitmap object to the user's DPI settings
   myBitmap.SetResolution(graphics)

   ' // Draw the bitmap.
   GdipDrawImage(graphics, myBitmap, 0, 0)

END SUB
' ========================================================================================

GdiPlusImageAttributes

An ImageAttributes object contains information about how bitmap and metafile colors are manipulated during rendering. An ImageAttributes object maintains several color-adjustment settings, including color-adjustment matrices, grayscale-adjustment matrices, gamma-correction values, color-map tables, and color-threshold values.

' ========================================================================================
TYPE GdiPlusImageAttributes
Public:
   m_ImgAttr AS GpImageAttributes PTR
   DECLARE CONSTRUCTOR (BYVAL imgAttr AS GpImageAttributes PTR = NULL)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpImageAttributes PTR PTR
   DECLARE OPERATOR CAST () AS GpImageAttributes PTR
END TYPE
' ========================================================================================

' ========================================================================================
' Default constructor
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusImageAttributes (BYVAL imgAttr AS GpImageAttributes PTR = NULL)
   IF imgAttr THEN
      SetLastError(GdipCloneImageAttributes(imgAttr, @m_ImgAttr))
   ELSE
      SetLastError(GdipCreateImageAttributes(@m_ImgAttr))
   END IF
END CONSTRUCTOR
' ========================================================================================

' ========================================================================================
' Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusImageAttributes
   IF m_ImgAttr THEN GdipDisposeImageAttributes(m_ImgAttr)
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpImageAttributes object
' ========================================================================================
PRIVATE OPERATOR * (BYREF imgAttr AS GdiPlusImageAttributes) AS GpImageAttributes PTR
   RETURN imgAttr.m_ImgAttr
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpImageAttributes object
' ========================================================================================
PRIVATE OPERATOR GdiPlusImageAttributes.@ () AS GpImageAttributes PTR PTR
   RETURN @m_ImgAttr
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusImageAttributes.CAST () AS GpImageAttributes PTR
   RETURN m_ImgAttr
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' The following example creates an Image object loading an image from file, creates an
' ImageAttributes object, sets the wrap mode to WrapModeTile and draws the specified
' source rectangle to the destination rectangle, which is four times as large as the
' image itself.
' ========================================================================================
SUB Example_CreateImageAttributes (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Load an image from file
   DIM image AS GdiPlusImage = "climber.jpg"
   ' // Set the resolution of this image object to the user's DPI settings
   image.SetResolution(graphics)
   
   ' // Get the width and height of the image
   DIM AS LONG nWidth, nHeight
   GdipGetImageWidth(image, @nWidth)
   GdipGetImageHeight(image, @nHeight)

   ' // Create an ImageAttributes object
   DIM imgAttr AS GdiPlusImageAttributes

   ' // Set the wrap mode to WrapModeTile
   GdipSetImageAttributesWrapMode(imgAttr, WrapModeTile, ARGB_BLUE, FALSE)

   ' // Draw the image
   GdipDrawImageRectRect(graphics, image, _
            10, 10, nWidth, nHeight, _         ' dest rect
            0, 0, 2 * nWidth, 2 * nHeight, _   ' source dest
            UnitPixel, imgAttr, NULL, NULL)

END SUB
' ========================================================================================

GdiPlusEffect

Allows to apply effects and adjustments to bitmaps.

' ========================================================================================
TYPE GdiPlusEffect
Public:
   m_Effect AS GpEffect PTR
   m_auxDataSize AS INT_
   m_auxData AS ANY PTR
   m_useAuxData AS BOOLEAN
   DECLARE CONSTRUCTOR (BYVAL gd AS GUID)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpEffect PTR PTR
   DECLARE OPERATOR CAST () AS GpEffect PTR
END TYPE
' ========================================================================================

' ========================================================================================
' Default constructor
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusEffect (BYVAL gd AS GUID)
   SetLastError GdipCreateEffect(gd, @m_Effect)
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusEffect
   ' // auxData is allocated by ApplyEffect.
   IF m_auxData THEN GdipFree(m_auxData)
   ' // Delete the Effect object
   IF m_Effect THEN GdipDeleteEffect(m_Effect)
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the CGpEffect object
' ========================================================================================
PRIVATE OPERATOR * (BYREF effect AS GdiPlusEffect) AS GpEffect PTR
   RETURN effect.m_Effect
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpEffect object
' ========================================================================================
PRIVATE OPERATOR GdiPlusEffect.@ () AS GpEffect PTR PTR
   RETURN @m_Effect
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusEffect.CAST () AS GpEffect PTR
   RETURN m_Effect
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' This example loads an image from disk and applies a blur effect using GDI+ 1.1.
' ========================================================================================
SUB Example_BlurEffect (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Create a bitmap object from a .jpg file
   DIM bmp AS GdiPlusBitmap = "climber.jpg"
   ' // Set the resolution of this Bitmap object to the user's DPI settings
   bmp.SetResolution(graphics)

   ' // Create a blur effect
   DIM effect AS GdiPlusEffect = BlurEffectGuid

   ' // Set parameters: radius = 6.0, expandEdge = FALSE
   DIM blurParams(0 TO 1) AS SINGLE = {6.0, FALSE}
   DIM array_size AS GpUnit = (UBOUND(blurParams) - LBOUND(blurParams) + 1) * SIZEOF(SINGLE)
   GdipSetEffectParameters(effect, @blurParams(0), array_size)

   ' // Apply effects to the whole image
   GdipBitmapApplyEffect(bmp, effect, NULL, FALSE, NULL, NULL)

   ' // Draw the image
   GdipDrawImage(graphics, bmp, 0, 0)

END SUB
' ========================================================================================

GdiPlusGraphics

The Graphics functions provide methods for drawing lines, curves, figures, images, and text. A Graphics object stores attributes of the display device and attributes of the items to be drawn.

' ========================================================================================
TYPE GdiPlusGraphics
Public:
   m_Graphics AS GpGraphics PTR
   DECLARE CONSTRUCTOR (BYVAL hdc AS HDC)
   DECLARE CONSTRUCTOR (BYVAL hdc AS HDC, BYVAL hDevice AS HANDLE)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpGraphics PTR PTR
   DECLARE OPERATOR CAST () AS GpGraphics PTR
   DECLARE FUNCTION DpiX () AS SINGLE
   DECLARE FUNCTION DpiY () AS SINGLE
   DECLARE FUNCTION DpiRatio () AS SINGLE
   DECLARE FUNCTION DpiRatioX () AS SINGLE
   DECLARE FUNCTION DpiRatioY () AS SINGLE
   DECLARE FUNCTION ScaleTransform (BYVAL sx AS SINGLE, BYVAL sy AS SINGLE, BYVAL order AS MatrixOrder = MatrixOrderPrepend) AS GpStatus
   DECLARE FUNCTION ScaleTransform (BYVAL dpiRatio_ AS SINGLE, BYVAL order AS MatrixOrder = MatrixOrderPrepend) AS GpStatus
   DECLARE FUNCTION ScaleTransform (BYVAL order AS MatrixOrder = MatrixOrderPrepend) AS GpStatus
END TYPE
' ========================================================================================

' ========================================================================================
' * Creates a Graphics object that is associated with a specified device context.
' When you use these constructors to create a Graphics object, make sure that the Graphics
' object is deleted or goes out of scope before the device context is released.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusGraphics (BYVAL hdc AS HDC)
   SetLastError(GdipCreateFromHDC(hdc, @m_Graphics))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusGraphics (BYVAL hdc AS HDC, BYVAL hDevice AS HANDLE)
   SetLastError(GdipCreateFromHDC2(hdc, hDevice, @m_Graphics))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' * Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusGraphics
   IF m_Graphics THEN SetLastError(GdipDeleteGraphics(m_Graphics))
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpGraphics object
' ========================================================================================
PRIVATE OPERATOR * (BYREF graphics AS GdiPlusGraphics) AS GpGraphics PTR
   RETURN graphics.m_Graphics
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpGraphics object
' ========================================================================================
PRIVATE OPERATOR GdiPlusGraphics.@ () AS GpGraphics PTR PTR
   RETURN @m_Graphics
END OPERATOR
' ========================================================================================

' ========================================================================================
PRIVATE OPERATOR GdiPlusGraphics.CAST () AS GpGraphics PTR
   RETURN m_Graphics
END OPERATOR
' ========================================================================================

' ========================================================================================
' Get the DPI scaling
' ========================================================================================
PRIVATE FUNCTION GdiPlusGraphics.DpiX () AS SINGLE
   DIM _dpiX AS SINGLE
   SetLastError(GdipGetDpiX(m_Graphics, @_dpiX))
   RETURN _dpiX
END FUNCTION
' ========================================================================================
' ========================================================================================
PRIVATE FUNCTION GdiPlusGraphics.DpiY () AS SINGLE
   DIM _dpiY AS SINGLE
   SetLastError(GdipGetDpiX(m_Graphics, @_dpiY))
   RETURN _dpiY
END FUNCTION
' ========================================================================================
' ========================================================================================
' Get the DPI scaling ratio
' ========================================================================================
PRIVATE FUNCTION GdiPlusGraphics.DpiRatio () AS SINGLE
   DIM _dpiX AS SINGLE
   SetLastError(GdipGetDpiX(m_Graphics, @_dpiX))
   DIM rxRatio AS SINGLE = _dpiX / 96
   RETURN rxRatio
END FUNCTION
' ========================================================================================
' ========================================================================================
PRIVATE FUNCTION GdiPlusGraphics.DpiRatioX () AS SINGLE
   DIM _dpiX AS SINGLE
   SetLastError(GdipGetDpiX(m_Graphics, @_dpiX))
   DIM rxRatio AS SINGLE = _dpiX / 96
   RETURN rxRatio
END FUNCTION
' ========================================================================================
' ========================================================================================
PRIVATE FUNCTION GdiPlusGraphics.DpiRatioY () AS SINGLE
   DIM _dpiY AS SINGLE
   SetLastError(GdipGetDpiY(m_Graphics, @_dpiY))
   DIM ryRatio AS SINGLE = _dpiY / 96
   RETURN ryRatio
END FUNCTION
' ========================================================================================
' ========================================================================================
' Updates this Graphic object's current transformation matrix with the product of itself
' and a scaling matrix.
' ========================================================================================
PRIVATE FUNCTION GdiPlusGraphics.ScaleTransform (BYVAL sx AS SINGLE, BYVAL sy AS SINGLE, BYVAL order AS MatrixOrder = MatrixOrderPrepend) AS GpStatus
   RETURN GdipScaleWorldTransform(m_Graphics, sx, sy, order)
END FUNCTION
' ========================================================================================
' ========================================================================================
PRIVATE FUNCTION GdiPlusGraphics.ScaleTransform (BYVAL dpiRatio_ AS SINGLE, BYVAL order AS MatrixOrder = MatrixOrderPrepend) AS GpStatus
   RETURN GdipScaleWorldTransform(m_Graphics, dpiRatio, dpiRatio_, order)
END FUNCTION
' ========================================================================================
' ========================================================================================
PRIVATE FUNCTION GdiPlusGraphics.ScaleTransform (BYVAL order AS MatrixOrder = MatrixOrderPrepend) AS GpStatus
   DIM _dpiX AS SINGLE
   GdipGetDpiX(m_Graphics, @_dpiX)
   DIM rxRatio AS SINGLE = _dpiX / 96
   DIM _dpiY AS SINGLE
   GdipGetDpiY(m_Graphics, @_dpiY)
   DIM ryRatio AS SINGLE = _dpiY / 96
   RETURN GdipScaleWorldTransform(m_Graphics, rxRatio, ryRatio, order)
END FUNCTION
' ========================================================================================

Example

' ========================================================================================
' The following example draws an image with its upper-left corner at (10, 10).
' ========================================================================================
SUB Example_DrawImage (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Create the Image object
   DIM image AS GdiPlusImage = "climber.jpg"
   image.SetResolution(graphics)

   ' // Draw the image
   GdipDrawImage(graphics, image, 10, 10)

END SUB
' ========================================================================================

GdiPlusFont

A Font object is used when drawing strings.

' ========================================================================================
TYPE GdiPlusFont
Public:
   m_Font AS GpFont PTR
   DECLARE CONSTRUCTOR (BYVAL font AS GpFont PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL hdc AS HDC)
   DECLARE CONSTRUCTOR (BYVAL hdc AS HDC, BYVAL plogfont AS LOGFONTA PTR)
   DECLARE CONSTRUCTOR (BYVAL hdc AS HDC, BYVAL plogfont AS LOGFONTW PTR)
   DECLARE CONSTRUCTOR (BYVAL fontFamily AS GpFontFamily PTR, BYVAL emSize AS SINGLE, BYVAL nStyle AS INT_ = 0, BYVAL nUnit AS GpUnit = 0)
   DECLARE CONSTRUCTOR (BYVAL pwszFamilyName AS WSTRING PTR, BYVAL emSize AS SINGLE, BYVAL nStyle AS INT_ = 0, BYVAL nUnit AS GpUnit = 0, BYVAL fontCollection AS GpFontCollection PTR = NULL)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpFont PTR PTR
   DECLARE OPERATOR CAST () AS GpFont PTR
END TYPE
' ========================================================================================

' ========================================================================================
' Creates and initializes a Font object from another Font object.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusFont (BYVAL font AS GpFont PTR = NULL)
   IF font THEN GdipCloneFont(font, @m_Font)
END CONSTRUCTOR
' =====================================================================================

' ========================================================================================
' Creates a Font object based on the GDI font object that is currently selected into a
' specified device context. This constructor is provided for compatibility with GDI.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusFont (BYVAL hdc AS HDC)
   SetLastError(GdipCreateFontFromDC(hdc, @m_Font))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates a Font object directly from a Windows Graphics Device Interface (GDI) logical
' font. The GDI logical font is a LOGFONTA structure, which is the one-byte character
' version of a logical font. This constructor is provided for compatibility with GDI.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusFont (BYVAL hdc AS HDC, BYVAL plogfont AS LOGFONTA PTR)
   IF plogfont <> NULL THEN
      SetLastError(GdipCreateFontFromLogfontA(hdc, plogfont, @m_Font))
   ELSE
      SetLastError(GdipCreateFontFromDC(hdc, @m_Font))
   END IF
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates a Font object directly from a Windows Graphics Device Interface (GDI) logical
' font. The GDI logical font is a LOGFONTW structure, which is the one-byte character
' version of a logical font. This constructor is provided for compatibility with GDI.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusFont (BYVAL hdc AS HDC, BYVAL plogfont AS LOGFONTW PTR)
   IF plogfont <> NULL THEN
      SetLastError(GdipCreateFontFromLogfontW(hdc, plogfont, @m_Font))
   ELSE
      SetLastError(GdipCreateFontFromDC(hdc, @m_Font))
   END IF
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates a Font object based on a FontFamily object, a size, a font style, and a unit of measurement.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusFont (BYVAL fontFamily AS GpFontFamily PTR, BYVAL emSize AS SINGLE, BYVAL nStyle AS INT_ = 0, BYVAL nUnit AS GpUnit = 0)
   SetLastError(GdipCreateFont(fontFamily, emSize, nStyle, nUnit, @m_Font))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates a Font object based on a font family, a size, a font style, a unit of
' measurement, and a FontCollection object.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusFont (BYVAL pwszFamilyName AS WSTRING PTR, BYVAL emSize AS SINGLE, BYVAL nStyle AS INT_ = 0, BYVAL nUnit AS GpUnit = 0, BYVAL fontCollection AS GpFontCollection PTR = NULL)
   DIM fontFamily AS GpFontFamily PTR
   SetLastError(GdipCreateFontFamilyFromName(pwszFamilyName, fontCollection, @fontFamily))
   IF fontFamily THEN
      SetLastError GdipCreateFont(fontFamily, emSize, nStyle, nUnit, @m_Font)
   ELSE
      SetLastError(GdipGetGenericFontFamilySansSerif(@fontFamily))
      SetLastError(GdipCreateFont(fontFamily, emSize, nStyle, nUnit, @m_Font))
   END IF
   IF fontFamily THEN GdipDeleteFontFamily(fontFamily)
END CONSTRUCTOR
' ========================================================================================
' ===========================================================================================
' Cleanup
' ===========================================================================================
PRIVATE DESTRUCTOR GdiPlusFont
   IF m_Font THEN GdipDeleteFont(m_Font)
END DESTRUCTOR
' ===========================================================================================
' ========================================================================================
' Returns a pointer to the GpFont object
' ========================================================================================
PRIVATE OPERATOR * (BYREF font AS GdiPlusFont) AS GpFont PTR
   RETURN font.m_Font
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpFont object
' ========================================================================================
PRIVATE OPERATOR GdiPlusFont.@ () AS GpFont PTR PTR
   RETURN @m_Font
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusFont.CAST () AS GpFont PTR
   RETURN m_Font
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' The following example creates a Font object and then uses it to draw text.
' ========================================================================================
SUB Example_CreateFont (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Create the font
   DIM fontFamily AS GdiPlusFontFamily = "Arial"
   DIM font AS GdiPlusFont = GdiPlusFont(*fontFamily, AfxGdipPointsToPixels(18, TRUE), FontStyleRegular, UnitPixel)

   ' // Create a solid brush
   DIM solidBrush AS GdiPlusSolidBrush = ARGB_BLUE

   ' // Draw a string
   DIM rcf AS GpRectF = (30, 30, 0, 0)
   DIM wszText AS WSTRING * 64 = "Text drawn using an Arial font"
   GdipDrawString(graphics, wszText, LEN(wszText), font, @rcf, NULL, solidBrush)

END SUB
' ========================================================================================

GdiPlusFontFamily

A font family is a group of fonts that have the same typeface but different styles.

' ========================================================================================
TYPE GdiPlusFontFamily
Public:
   m_FontFamily AS GpFontFamily PTR
   DECLARE CONSTRUCTOR (BYVAL fontFamily AS GpFontFamily PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL pwszName AS WSTRING PTR, BYVAL fontCollection AS GpFontCollection PTR = NULL)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpFontFamily PTR PTR
   DECLARE OPERATOR CAST () AS GpFontFamily PTR
END TYPE
' ========================================================================================

' ========================================================================================
' Creates and initializes a FontFamily object from another FontFamily object.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusFontFamily (BYVAL fontFamily AS GpFontFamily PTR = NULL)
   IF fontFamily THEN SetLastError(GdipCloneFontFamily(fontFamily, @m_FontFamily))
END CONSTRUCTOR
' =====================================================================================
' ========================================================================================
' Creates a FontFamily object based on a specified font collection.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusFontFamily (BYVAL pwszName AS WSTRING PTR, BYVAL fontCollection AS GpFontCollection PTR = NULL)
   SetLastError(GdipCreateFontFamilyFromName(pwszName, fontCollection, @m_FontFamily))
END CONSTRUCTOR
' ========================================================================================
' =====================================================================================
' Cleanup
' =====================================================================================
PRIVATE DESTRUCTOR GdiPlusFontFamily
   IF m_FontFamily THEN GdipDeleteFontFamily(m_FontFamily)
END DESTRUCTOR
' =====================================================================================
' ========================================================================================
' Returns a pointer to the GpFontFamily object
' ========================================================================================
PRIVATE OPERATOR * (BYREF fontFamily AS GdiPlusFontFamily) AS GpFontFamily PTR
   RETURN fontFamily.m_FontFamily
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpFontFamily object
' ========================================================================================
PRIVATE OPERATOR GdiPlusFontFamily.@ () AS GpFontFamily PTR PTR
   RETURN @m_FontFamily
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusFontFamily.CAST () AS GpFontFamily PTR
   RETURN m_FontFamily
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' The following example creates a Font object from a font family and then uses it to draw text.
' ========================================================================================
SUB Example_CreateFontFromFamily (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Create the font
   DIM fontFamily AS GdiPlusFontFamily = "Arial"
   DIM font AS GdiPlusFont = GdiPlusFont(*fontFamily, AfxGdipPointsToPixels(14, TRUE), FontStyleRegular, UnitPixel)

   ' // Create a solid brush
   DIM solidBrush AS GdiPlusSolidBrush = ARGB_BLUE

   ' // Draw a string
   DIM rcf AS GpRectF = (30, 30, 0, 0)
   DIM wszText AS WSTRING * 64 = "This is a Font created from a FontFamily"
   GdipDrawString(graphics, wszText, LEN(wszText), font, @rcf, NULL, solidBrush)

END SUB
' ========================================================================================

GdiPlusGraphicsPath

A GraphicsPath object stores a sequence of lines, curves, and shapes. You can draw the entire sequence by calling the GdipDrawPath function. You can partition the sequence of lines, curves, and shapes into figures, and with the help of the PathIterator functions, you can draw selected figures. You can also place markers in the sequence, so that you can draw selected portions of the path.

' ========================================================================================
TYPE GdiPlusGraphicsPath
Public:
   m_Path AS GpPath PTR
   DECLARE CONSTRUCTOR (BYVAL path AS GpPath PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL nFillMode AS FillMode)
   DECLARE CONSTRUCTOR (BYVAL pts AS GpPointF PTR, BYVAL types AS BYTE PTR, BYVAL nCount AS LONG, BYVAL nFillMode AS FillMode = FillModeAlternate)
   DECLARE CONSTRUCTOR (BYVAL pts AS GpPoint PTR, BYVAL types AS BYTE PTR, BYVAL nCount AS LONG, BYVAL nFillMode AS FillMode = FillModeAlternate)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpPath PTR PTR
   DECLARE OPERATOR CAST () AS GpPath PTR
END TYPE
' ========================================================================================

' =====================================================================================
' Constructors
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusGraphicsPath (BYVAL path AS GpPath PTR = NULL)
   IF path THEN SetLastError(GdipClonePath(path, @m_Path))
END CONSTRUCTOR
' =====================================================================================
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusGraphicsPath (BYVAL nFillMode AS FillMode)
   SetLastError(GdipCreatePath(nFillMode, @m_Path))
END CONSTRUCTOR
' ========================================================================================
' =====================================================================================
' Creates a GraphicsPath object based on an array of points, an array of types, and a fill mode.
' Default value for fillMode: FillModeAlternate(0).
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusGraphicsPath (BYVAL pts AS GpPointF PTR, BYVAL types AS BYTE PTR, BYVAL nCount AS LONG, BYVAL nFillMode AS FillMode = FillModeAlternate)
   SetLastError(GdipCreatePath2(pts, types, nCount, nFillmode, @m_Path))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusGraphicsPath (BYVAL pts AS GpPoint PTR, BYVAL types AS BYTE PTR, BYVAL nCount AS LONG, BYVAL nFillMode AS FillMode = FillModeAlternate)
   SetLastError(GdipCreatePath2I(pts, types, nCount, nFillmode, @m_Path))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
' Cleanup
' =====================================================================================
PRIVATE DESTRUCTOR GdiPlusGraphicsPath
   IF m_Path THEN GdipDeletePath(m_Path)
END DESTRUCTOR
' =====================================================================================
' ========================================================================================
' Returns a pointer to the GpGraphicsPath object
' ========================================================================================
PRIVATE OPERATOR * (BYREF path AS GdiPlusGraphicsPath) AS GpPath PTR
   RETURN path.m_Path
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpGraphicsPath object
' ========================================================================================
PRIVATE OPERATOR GdiPlusGraphicsPath.@ () AS GpPath PTR PTR
   RETURN @m_Path
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusGraphicsPath.CAST () AS GpPath PTR
   RETURN m_Path
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' This example creates a GraphicsPath and adds a shape to it.
' ========================================================================================
SUB Example_CreatePath (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Create GraphicsPath
   DIM path AS GdiPlusGraphicsPath = FillModeAlternate

   ' // Add a shape to the path
   GdipAddPathEllipse(path, 120, 80, 150, 100)

   ' // Create pen
   DIM pen AS GdiPlusPen = GdiPlusPen(ARGB_MIDNIGHTBLUE, 2, UnitWorld)

   ' // Draw path
   GdipDrawPath(graphics, pen, path)

END SUB
' ========================================================================================

GdiPlusMatrix

A Matrix object represents a 3 ×3 matrix that, in turn, represents an affine transformation. A Matrix object stores only six of the 9 numbers in a 3 ×3 matrix because all 3 ×3 matrices that represent affine transformations have the same third column (0, 0, 1).

' ========================================================================================
TYPE GdiPlusMatrix
Public:
   m_Matrix AS GpMatrix PTR
   DECLARE CONSTRUCTOR (BYVAL matrix AS GpMatrix PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL m11 AS SINGLE, BYVAL m12 AS SINGLE, BYVAL m21 AS SINGLE, BYVAL m22 AS SINGLE, BYVAL dx AS SINGLE, BYVAL dy AS SINGLE)
   DECLARE CONSTRUCTOR (BYVAL rcf AS GpRectF PTR, BYVAL dstplg AS GpPointF PTR)
   DECLARE CONSTRUCTOR (BYVAL rc AS GpRect PTR, BYVAL dstplg AS GpPoint PTR)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR CAST () AS GpMatrix PTR
   DECLARE OPERATOR @ () AS GpMatrix PTR PTR
END TYPE
' ========================================================================================

' ========================================================================================
' Constructors
' ========================================================================================
' ========================================================================================
' Creates and initializes a Matrix object from another Matrix object
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusMatrix (BYVAL matrix AS GpMatrix PTR = NULL)
   IF matrix THEN
      SetLastError(GdipCloneMatrix(matrix, @m_Matrix))
   ELSE
      SetLastError(GdipCreateMatrix(@m_Matrix))
   END IF
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Creates and initializes a Matrix object based on six numbers that define an affine transformation.
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusMatrix (BYVAL m11 AS SINGLE, BYVAL m12 AS SINGLE, BYVAL m21 AS SINGLE, BYVAL m22 AS SINGLE, BYVAL dx AS SINGLE, BYVAL dy AS SINGLE)
   SetLastError(GdipCreateMatrix2(m11, m12, m21, m22, dx, dy, @m_Matrix))
END CONSTRUCTOR
' ========================================================================================
' =====================================================================================
' Creates a Matrix object based on a rectangle and a point.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusMatrix (BYVAL rcf AS GpRectF PTR, BYVAL dstplg AS GpPointF PTR)
   SetLastError(GdipCreateMatrix3(rcf, dstplg, @m_Matrix))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
' Creates a Matrix object based on a rectangle and a point.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusMatrix (BYVAL rc AS GpRect PTR, BYVAL dstplg AS GpPoint PTR)
   SetLastError(GdipCreateMatrix3I(rc, dstplg, @m_Matrix))
END CONSTRUCTOR
' =====================================================================================
' ========================================================================================
' * Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusMatrix
   IF m_Matrix THEN GdipDeleteMatrix(m_Matrix)
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpMatrix object
' ========================================================================================
PRIVATE OPERATOR * (BYREF matrix AS GdiPlusMatrix) AS GpMatrix PTR
   RETURN matrix.m_Matrix
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusMatrix.CAST () AS GpMatrix PTR
   RETURN m_Matrix
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpMatrix object
' ========================================================================================
PRIVATE OPERATOR GdiPlusMatrix.@ () AS GpMatrix PTR PTR
   RETURN @m_Matrix
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' Creates a transformation matrix based on a source rectangle and a destination parallelogram.
' This is especially useful for mapping one shape onto another—like skewing, rotating, or
' stretching a rectangle into a custom shape.
' ========================================================================================
SUB Example_CreateMatrix3 (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Define source rectangle
   DIM srcRect AS GpRectF = (0, 0, 100, 60)

   ' // Define destination parallelogram points
   DIM destPoints(0 TO 2) AS GpPointF
   destPoints(0).x = 50  : destPoints(0).y = 50      ' Top-left
   destPoints(1).x = 160 : destPoints(1).y = 40      ' Top-right
   destPoints(2).x = 60  : destPoints(2).y = 120     ' Bottom-left

   ' // Create matrix to map srcRect to dstPoints
   DIM matrix AS GdiPlusMatrix = GdiPlusMatrix(@srcRect, @destPoints(0))

   ' // Apply matrix to graphics
   GdipSetWorldTransform(graphics, matrix)

   ' // Create pen
   DIM pen AS GdiPlusPen = GdiPlusPen(ARGB_RED, 2 * graphics.dpiRatio, UnitPixel)

   ' // Draw transformed rectangle
   GdipScaleWorldTransform(graphics, graphics.dpiRatioX, graphics.dpiRatioY, MatrixOrderPrepend)
   GdipDrawRectangle(graphics, pen, 0, 0, 100, 60)

END SUB
' ========================================================================================

GdiPlusPathIterator

The PathIterator functions allow to isolate selected subsets of the path stored in a GraphicsPath object. A path consists of one or more figures. You can use a GraphicsPathIterator to isolate one or more of those figures. A path can also have markers that divide the path into sections. You can use a GraphicsPathIterator object to isolate one or more of those sections.

' ========================================================================================
TYPE GdiPlusPathIterator
Public:
   m_PathIretator AS GpPathIterator PTR
   DECLARE CONSTRUCTOR (BYVAL path AS GpPath PTR)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpPathIterator PTR PTR
   DECLARE OPERATOR CAST () AS GpPathIterator PTR
END TYPE
' ========================================================================================

' =====================================================================================
' Creates a new CGpGraphicsPathIterator object and associates it with a CGpGraphicsPath object.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusPathIterator (BYVAL path AS GpPath PTR)
   SetLasTError(GdipCreatePathIter(@m_pathIretator, path))
END CONSTRUCTOR
' =====================================================================================
' ========================================================================================
' Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusPathIterator
   IF m_PathIretator THEN GdipDeletePathIter(m_PathIretator)
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpPathIterator object
' ========================================================================================
PRIVATE OPERATOR * (BYREF pathIterator AS GdiPlusPathIterator) AS GpPathIterator PTR
   RETURN pathIterator.m_PathIretator
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpPathIterator object
' ========================================================================================
PRIVATE OPERATOR GdiPlusPathIterator.@ () AS GpPathIterator PTR PTR
   RETURN @m_PathIretator
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusPathIterator.CAST () AS GpPathIterator PTR
   RETURN m_PathIretator
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' This example demonstrates
' How to build a path with multiple figures.
' How to use PathIterator to inspect each figure’s bounds and closure status.
' ========================================================================================
SUB Example_CreatePathIter (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' Create a GraphicsPath with two figures
   DIM path AS GdiPlusGraphicsPath = FillModeAlternate

   ' First figure: triangle (closed)
   GdipAddPathLine(path, 10, 10, 100, 10)
   GdipAddPathLine(path, 100, 10, 55, 80)
   GdipClosePathFigure(path)

   ' Second figure: open zigzag
   GdipStartPathFigure(path)
   GdipAddPathLine(path, 120, 10, 180, 50)
   GdipAddPathLine(path, 180, 50, 120, 90)

   ' Create PathIterator
   DIM iterator AS GdiPlusPathIterator = *path

   ' Get subpath count
   DIM subpathCount AS LONG
   GdipPathIterGetSubpathCount(iterator, @subpathCount)

   ' Create font and brush for drawing text
   DIM fontFamily AS GdiPlusFontFamily ="Arial"
   DIM font AS GdiPlusFont = GdiPlusFont(*fontFamily, AfxGdipPointsToPixels(12, TRUE), FontStyleRegular, UnitPixel)
   DIM brush AS GdiPlusSolidBrush = ARGB_BLACK

   ' Iterate through subpaths and draw info
   DIM resultCount AS LONG, startIdx AS LONG, endIdx AS LONG
   DIM isClosed AS BOOL
   DIM yOffset AS SINGLE = 10.0

   FOR i AS LONG = 1 TO subpathCount
      GdipPathIterNextSubpath(iterator, @resultCount, @startIdx, @endIdx, @isClosed)
      DIM info AS STRING
      info = "Subpath " & i & ": Start=" & startIdx & ", End=" & endIdx & ", Closed=" & IIF(isClosed, "True", "False")
      DIM layout AS GpRectF = (10 * graphics.dpiRatioX, yOffset * graphics.dpiRatioY, 300 * graphics.dpiRatioX, 20 * graphics.dpiRatioY)
      GdipDrawString(graphics, info, -1, font, @layout, NULL, brush)
      yOffset += 20.0
   NEXT

END SUB
' ========================================================================================

GdiPlusPen

A Pen object is a Microsoft Windows GDI+ object used to draw lines and curves.

' ========================================================================================
TYPE GdiPlusPen
Public:
   m_Pen AS GpPen PTR
   DECLARE CONSTRUCTOR (BYVAL pen AS GpPen PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL colour AS ARGB, BYVAL nWidth AS SINGLE = 1.0, BYVAL unit AS GpUnit = UnitWorld)
   DECLARE CONSTRUCTOR (BYVAL brush AS GpBrush PTR, BYVAL nWidth AS SINGLE, BYVAL unit AS GpUnit = UnitWorld)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpPen PTR PTR
   DECLARE OPERATOR CAST () AS GpPen PTR
END TYPE
' ========================================================================================

' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusPen (BYVAL pen AS GpPen PTR = NULL)
   IF pen THEN SetLastError(GdipClonePen(pen, @m_Pen))
END CONSTRUCTOR
' =====================================================================================

' =====================================================================================
' * Creates a Pen object that uses a specified color and width.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusPen (BYVAL colour AS ARGB, BYVAL nWidth AS SINGLE = 1.0, BYVAL unit AS GpUnit = UnitWorld)
   SetLastError(GdipCreatePen1(colour, nWidth, unit, @m_Pen))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
' Creates a Pen object that uses the attributes of a brush and a real number to set the
' width of this Pen object.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusPen (BYVAL brush AS GpBrush PTR, BYVAL nWidth AS SINGLE, BYVAL unit AS GpUnit = UnitWorld)
   SetLastError(GdipCreatePen2(brush, nWidth, unit, @m_Pen))
END CONSTRUCTOR
' =====================================================================================
' ========================================================================================
' * Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusPen
   IF m_Pen THEN SetLastError(GdipDeletePen(m_Pen))
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpPen object
' ========================================================================================
PRIVATE OPERATOR * (BYREF pen AS GdiPlusPen) AS GpPen PTR
   RETURN pen.m_Pen
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpPen object
' ========================================================================================
PRIVATE OPERATOR GdiPlusPen.@ () AS GpPen PTR PTR
   RETURN @m_Pen
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusPen.CAST () AS GpPen PTR
   RETURN m_Pen
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' The following example creates a Pen object, creates a copy of the Pen object, and then
' draws an ellipse using the cloned Pen object.
' ========================================================================================
SUB Example_ClonePen (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Create a Pen
   DIM pen AS GdiPlusPen = GdiPlusPen(ARGB_RED, 4, UnitWorld)
   ' // Clone it
   DIM clonedPen AS GdiPlusPen = *pen

   ' // Draw a rectangle using the cloned Pen object.
   GdipDrawRectangleI(graphics, clonedPen, 10, 10, 100, 50)

END SUB
' ========================================================================================

GdiPlusRegion

A Region describes an area of the display surface. The area can be any shape. In other words, the boundary of the area can be a combination of curved and straight lines. Regions can also be created from the interiors of rectangles, paths, or a combination of these. Regions are used in clipping and hit-testing operations.

' ========================================================================================
TYPE GdiPlusRegion
Public:
   m_Region AS GpRegion PTR
   DECLARE CONSTRUCTOR (BYVAL region AS GpRegion PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL rcf AS GpRectF PTR)
   DECLARE CONSTRUCTOR (BYVAL rc AS GpRect PTR)
   DECLARE CONSTRUCTOR (BYVAL x AS SINGLE, BYVAL y AS SINGLE, BYVAL nWidth AS SINGLE, BYVAL nHeight AS SINGLE)
   DECLARE CONSTRUCTOR (BYVAL x AS INT_, BYVAL y AS INT_, BYVAL nWidth AS INT_, BYVAL nHeight AS INT_)
   DECLARE CONSTRUCTOR (BYVAL regionData AS BYTE PTR, BYVAL nSize AS LONG)
   DECLARE CONSTRUCTOR (BYVAL hRgn AS HRGN)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpRegion PTR PTR
   DECLARE OPERATOR CAST () AS GpRegion PTR
   DECLARE SUB FromPath (BYVAL pah AS GpPath PTR)
END TYPE
' ========================================================================================

' =====================================================================================
' Default constructor
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusRegion (BYVAL region AS GpRegion PTR = NULL)
   IF region THEN
      SetLastError(GdipCloneRegion(region, @m_Region))
   ELSE
      SetLastError(GdipCreateRegion(@m_Region))
   END IF
END CONSTRUCTOR
' =====================================================================================
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusRegion (BYVAL rcf AS GpRectF PTR)
   SetLastError(GdipCreateRegionRect(rcf, @m_Region))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusRegion (BYVAL rc AS GpRect PTR)
   SetLastError(GdipCreateRegionRectI(rc, @m_Region))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusRegion (BYVAL x AS SINGLE, BYVAL y AS SINGLE, BYVAL nWidth AS SINGLE, BYVAL nHeight AS SINGLE)
   DIM rcf AS GpRectF : rcf.x = x : rcf.y = y : rcf.Width = nwidth : rcf.Height = nHeight
   SetLastError(GdipCreateRegionRect(@rcf, @m_Region))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
PRIVATE CONSTRUCTOR GdiPlusRegion (BYVAL x AS INT_, BYVAL y AS INT_, BYVAL nWidth AS INT_, BYVAL nHeight AS INT_)
   DIM rc AS GpRect : rc.x = x : rc.y = y : rc.Width = nwidth : rc.Height = nHeight
   SetLastError(GdipCreateRegionRectI(@rc, @m_Region))
END CONSTRUCTOR
' ========================================================================================
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusRegion (BYVAL regionData AS BYTE PTR, BYVAL nSize AS LONG)
   SetLastError(GdipCreateRegionRgnData(regionData, nSize, @m_Region))
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusRegion (BYVAL hRgn AS HRGN)
   SetLastError(GdipCreateRegionHrgn(hRgn, @m_Region))
END CONSTRUCTOR
' =====================================================================================
' ========================================================================================
' Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusRegion
   IF m_Region THEN GdipDeleteRegion(m_Region)
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpRegion object
' ========================================================================================
PRIVATE OPERATOR * (BYREF region AS GdiPlusRegion) AS GpRegion PTR
   RETURN region.m_Region
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpRegion object
' ========================================================================================
PRIVATE OPERATOR GdiPlusRegion.@ () AS GpRegion PTR PTR
   RETURN @m_Region
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusRegion.CAST () AS GpRegion PTR
   RETURN m_Region
END OPERATOR
' ========================================================================================
' =====================================================================================
' Creates a region from a path
' A separate function is needed because using a constructor conflicts with the default one.
' =====================================================================================
PRIVATE SUB GdiPlusRegion.FromPath (BYVAL path AS GpPath PTR)
   SetLastError(GdipCreateRegionPath(path, @m_Region))
END SUB
' =====================================================================================

Example

' ========================================================================================
' Creates a region that is identical to the region that is specified by a handle to a
' Microsoft Windows Graphics Device Interface (GDI) region.
' ========================================================================================
SUB Example_CreateRegionHrgn (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Create a simple GDI region (an ellipse)
   DIM hRgn AS HRGN = CreateEllipticRgn(50, 50, 200, 150)

   ' // Convert the GDI region to a GDI+ region
   DIM gdipRegion AS GdiPlusRegion = hRgn

   ' // Fill the GDI+ region with a brush
   DIM brush AS GdiPlusSolidBrush = ARGB_GREEN
   GdipFillRegion(graphics, brush, gdipRegion)

   ' // Cleanup
   IF hRgn THEN DeleteObject(hRgn)

END SUB
' ========================================================================================

GdiPlusStringFormat

The StringFormat functions allow to set and get text layout information (such as alignment, orientation, tab stops, and clipping) and display manipulations (such as trimming, font substitution for characters that are not supported by the requested font, and digit substitution for languages that do not use Western European digits). A StringFormat object can be passed to the GdipDrawString function to format a string.

' ========================================================================================
TYPE GdiPlusStringFormat
Public:
   m_StringFormat AS GpStringFormat PTR
   DECLARE CONSTRUCTOR (BYVAL stringFormat AS GpStringFormat PTR = NULL)
   DECLARE CONSTRUCTOR (BYVAL formatAttributes AS INT_, BYVAL language AS LANGID)
   DECLARE DESTRUCTOR
   DECLARE OPERATOR @ () AS GpStringFormat PTR PTR
   DECLARE OPERATOR CAST () AS GpStringFormat PTR
END TYPE
' ========================================================================================

' =====================================================================================
' Creates and initializes a default StringFormat object or clones it from another StringFormat object.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusStringFormat (BYVAL stringFormat AS GpStringFormat PTR = NULL)
   IF stringFormat THEN
      SetLastError(GdipCloneStringFormat(stringFormat, @m_StringFormat))
   ELSE
      SetLastError(GdipCreateStringFormat(0, LANG_NEUTRAL, @m_StringFormat))
   END IF
END CONSTRUCTOR
' =====================================================================================
' =====================================================================================
' Creates a StringFormat object based on string format flags and a language.
' =====================================================================================
PRIVATE CONSTRUCTOR GdiPlusStringFormat (BYVAL formatFlags AS INT_ = 0, BYVAL language AS LANGID = LANG_NEUTRAL)
   SetLastError(GdipCreateStringFormat(formatFlags, language, @m_StringFormat))
END CONSTRUCTOR
' ========================================================================================
' ========================================================================================
' Cleanup
' ========================================================================================
PRIVATE DESTRUCTOR GdiPlusStringFormat
   IF m_StringFormat THEN SetLastError(GdipDeleteStringFormat(m_StringFormat))
END DESTRUCTOR
' ========================================================================================
' ========================================================================================
' Returns a pointer to the GpStringFormat object
' ========================================================================================
PRIVATE OPERATOR * (BYREF fmt AS GdiPlusStringFormat) AS GpStringFormat PTR
   RETURN fmt.m_StringFormat
END OPERATOR
' ========================================================================================
' ========================================================================================
' Returns the address of a pointer to the GpStringFormat object
' ========================================================================================
PRIVATE OPERATOR GdiPlusStringFormat.@ () AS GpStringFormat PTR PTR
   RETURN @m_StringFormat
END OPERATOR
' ========================================================================================
' ========================================================================================
PRIVATE OPERATOR GdiPlusStringFormat.CAST () AS GpStringFormat PTR
   RETURN m_StringFormat
END OPERATOR
' ========================================================================================

Example

' ========================================================================================
' The following example uses the specified formatting to draw a string in a layout rectangle.
' ========================================================================================
SUB Example_CreateStringFormat (BYVAL hdc AS HDC)

   ' // Create a graphics object from the device context
   DIM graphics AS GdiPlusGraphics = hdc
   ' // Set the scale transform
   graphics.ScaleTransform

   ' // Create the font
   DIM fontFamily AS GdiPlusFontFamily ="Times New Roman"
   DIM font AS GdiPlusFont = GdiPlusFont(*fontFamily, AfxGdipPointsToPixels(16, TRUE), FontStyleRegular, UnitPixel)

   ' // Create a StringFormat object
   DIM format AS GdiPlusStringFormat = GdiPlusStringFormat(0, LANG_NEUTRAL)
   GdipSetStringFormatAlign(format, StringAlignmentCenter)

   ' // Create a solid brush
   DIM solidBrush AS GdiPlusSolidBrush = ARGB_BLACK

   ' // Draw the string
   DIM wszText AS WSTRING * 64 = "Sample text"
   DIM rcf AS GpRectF = (30, 30, 200, 25)
   GdipDrawString(graphics, wszText, LEN(wszText), font, @rcf, format, solidBrush)

   ' // Create a Pen
   DIM pen AS GdiPlusPen = GdiPlusPen(ARGB_BLACK, 3, UnitPixel)
   GdipScalePenTransform(pen, graphics.dpiRatioX, graphics.dpiRatioY, MatrixOrderPrepend)

   ' // Draw a rectangle
   GdipDrawRectangle(graphics, *pen, rcf.x, rcf.y, rcf.Width, rcf.Height)

END SUB
' ========================================================================================